<?php


namespace common\service;

use common\exception\LogicException;
use common\model\DelayOrderModel;
use common\model\DelayOrderTaskModel;
use common\model\DelayOrderTaskStepCategoryConfirmModel;
use common\model\EntityModel;
use common\model\ProjectMemberModel;
use common\model\ProjectModel;
use common\model\TagRelationModel;
use common\model\TaskModel;
use common\model\TaskRelationTagModel;
use common\model\UserModel;
use Exception;
use support\ErrorCode;
use support\SingletonTrait;
use think\Hook;
use Throwable;
use Webman\Stomp\Client;


class DelayOrderTaskStepCategoryConfirmService
{
    use SingletonTrait;

    /**
     * 创建环节确认记录
     * @param $delayOrder
     * @param $newDelayOrderTaskList
     * @param array $downstreamStepCategoryIdList
     * @param array $taskListMap
     * @param array $needConfirmTaskIdList
     * @param array $autoConfirmSelfStepCategoryAndCloseTaskIdList
     * @return array|bool|int|string
     * @throws Exception
     */
    public function createDelayOrderTaskStepCategoryConfirm($delayOrder, $newDelayOrderTaskList, array $downstreamStepCategoryIdList, array $taskListMap, array $needConfirmTaskIdList, array $autoConfirmSelfStepCategoryAndCloseTaskIdList)
    {
        $insertData = [];
        $created = time();
        $createdBy = fill_created_by();
        foreach ($newDelayOrderTaskList as $delayOrderTask) {
            $delayOrderTaskId = $delayOrderTask['id'];
            $taskId = $delayOrderTask['task_id'];
            $task = $taskListMap[$taskId];
            $isTodo = $task['step_type'] != TaskModel::STEP_TYPE_STEP;
            $lastUUID = '';
            $needConfirm = in_array($delayOrderTask['task_id'], $needConfirmTaskIdList);
            $autoConfirm = $autoConfirmSelfStepCategoryAndCloseTaskIdList[$delayOrderTask['task_id']] ?? null;
            foreach ($downstreamStepCategoryIdList as $index => $downstreamStepCategoryId) {
                $uuid = create_uuid();
                $tmp = [
                    'parent_uuid' => $lastUUID,
                    'uuid' => $uuid,
                    'delay_order_id' => $delayOrder['id'],
                    'delay_order_task_id' => $delayOrderTaskId,
                    'step_category_id' => $downstreamStepCategoryId,
                    'created' => $created,
                    'created_by' => $createdBy,
                    'is_active' => $needConfirm && $index === 0 ? 'yes' : 'no',
                    'is_self_step_category' => $index === 0 ? 'yes' : 'no',
                    'is_pass' => 'no',
                    'need_delay' => 'no',
                    'delay_to' => 0,
                    'delay_reason' => '',
                ];
                // 自动确认 填充自动确认的延期数据
                if (!empty($autoConfirm) && $index === 0) {
                    $tmp['is_active'] = 'no';
                    $tmp['is_pass'] = 'yes';
                    $tmp['need_delay'] = 'yes';
                    $tmp['delay_to'] = $autoConfirm['delay_time'];
                    $tmp['delay_reason'] = $autoConfirm['delay_reason'] ?? '';
                }
                $insertData[] = $tmp;
                $lastUUID = $uuid;
                // 待办任务 只有第一个环节(本环节)需要确认
                if ($isTodo) {
                    break;
                }
            }
        }
        $res = [];
        if (!empty($insertData)) {
            $res = model(DelayOrderTaskStepCategoryConfirmModel::class)->addAll($insertData);
        }
        return $res;
    }

    /**
     * 追加下游环节确认记录
     * @param array $uuidList
     * @return array|bool|int|string
     * @throws Exception
     */
    public function appendDelayOrderTaskStepCategoryConfirmByUuid(array $uuidList)
    {
        // 如果还有下游任务，继续创建该任务的下游任务确认
        // 如果存在该下游已经存在则不添加确认记录

        // 一、查出当前标准任务节点清单
        // 过滤任务类型
        $taskStepType = [
            TaskModel::STEP_TYPE_STANDARD_MEETING,
            TaskModel::STEP_TYPE_STANDARD_REVIEW,
            TaskModel::STEP_TYPE_TO_DO,
            TaskModel::STEP_TYPE_STANDARD_MAKE_TO_DO,
        ];
        $dotsscList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->join('delay_order_task on delay_order_task.id = delay_order_task_step_category_confirm.delay_order_task_id')
            ->join('task on task.id = delay_order_task.task_id')
            ->where([
                'delay_order_task_step_category_confirm.uuid' => ['in', $uuidList],
                'task.step_type' => ['in', implode(',', $taskStepType)]
            ])
            ->field(
                'delay_order_task.task_id'
                . ', delay_order_task_step_category_confirm.uuid'
                . ', delay_order_task_step_category_confirm.delay_order_id'
                . ', delay_order_task_step_category_confirm.delay_order_task_id'
                . ', delay_order_task_step_category_confirm.affected_task'
            )
            ->select();
        if (empty($dotsscList)) {
            return [];
        }
        // 查找在本次延期中，已受影响的任务，按延期任务id组织
        $existedTaskList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->where([
                'delay_order_task_step_category_confirm.delay_order_task_id' => ['in', array_column($dotsscList, 'delay_order_task_id')],
                'is_pass' => 'yes',
                'need_delay' => 'yes',
            ])
            ->field(
                'delay_order_task_step_category_confirm.delay_order_task_id'
                . ', delay_order_task_step_category_confirm.affected_task'
            )
            ->select();
        $existedTaskList = array_group_by($existedTaskList, 'delay_order_task_id');
        $allAffectedTaskList = [];
        $dotsscList = array_column($dotsscList, null, 'delay_order_task_id');
        foreach ($existedTaskList as $item) {
            $item = [
                'delay_order_task_id' => $item[0]['delay_order_task_id'],
                'affected_task' => implode(',', array_column($item, 'affected_task'))
            ];
            $uuidKey = $dotsscList[$item['delay_order_task_id']]['uuid'];
            if (!isset($existedTaskList[$uuidKey])) {
                $allAffectedTaskList[$uuidKey] = [$dotsscList[$item['delay_order_task_id']]['task_id']];
            }
            $currentAffectedTask = split_array($item['affected_task']);
            if (!empty($currentAffectedTask)) {
                $allAffectedTaskList[$uuidKey] = array_merge($allAffectedTaskList[$uuidKey], $currentAffectedTask);
            }
        }

        // 二、组装uuid-任务map, 查询任务的下游环节-任务map
        $dotsscList = array_column($dotsscList, null, 'uuid');
        $uuidTaskListMap = [];
        $allTaskList = [];
        foreach ($dotsscList as $uuid => $item) {
            // 当前任务列表
            $currentTaskList = split_array($item['affected_task']);
            if (empty($currentTaskList)) {
                $currentTaskList = [$item['task_id']];
            }
            $uuidTaskListMap[$item['uuid']] = $currentTaskList;
            $allTaskList = array_merge($allTaskList, $currentTaskList);
        }
        $allTaskList = array_unique($allTaskList);
        $excludeTaskStatus = StatusService::getInstance()->byCodeMap(['closed', 'final'], true, 'id');
        $taskDownstreamMap = StepCategoryService::getInstance()->getNextStepCategoryFromTaskRelation([
            'task_id_list' => $allTaskList,
            'task_step_type' => $taskStepType,
            'exclude_task_status' => $excludeTaskStatus
        ]);


        // 三、按节点、按环节 创建新的延期环节确认
        $insertData = [];
        $created = time();
        $createdBy = fill_created_by();
        foreach ($uuidTaskListMap as $parentUuid => $taskIdList) {
            $currentDownstreamMap = array_filter($taskDownstreamMap, fn($k) => in_array($k, $taskIdList), ARRAY_FILTER_USE_KEY);
            // 环节任务列表分组
            $currentDownstreamStepCategoryMap = [];
            foreach ($currentDownstreamMap as $taskId => $stepCategoryMap) {
                foreach ($stepCategoryMap as $stepCategoryId => $taskList) {
                    if (!isset($currentDownstreamStepCategoryMap[$stepCategoryId])) {
                        $currentDownstreamStepCategoryMap[$stepCategoryId] = [];
                    }
                    // 过滤已有的任务，不添加至环节确认列表
                    $taskList = array_diff($taskList, $allAffectedTaskList[$parentUuid]);
                    $currentDownstreamStepCategoryMap[$stepCategoryId] = array_merge($currentDownstreamStepCategoryMap[$stepCategoryId], $taskList);
                }
            }
            foreach ($currentDownstreamStepCategoryMap as $downstreamStepCategoryId => $taskList) {
                $uuid = create_uuid();
                $tmp = [
                    'parent_uuid' => $parentUuid,
                    'uuid' => $uuid,
                    'delay_order_id' => $dotsscList[$parentUuid]['delay_order_id'],
                    'delay_order_task_id' => $dotsscList[$parentUuid]['delay_order_task_id'],
                    'step_category_id' => $downstreamStepCategoryId,
                    'created' => $created,
                    'created_by' => $createdBy,
                    'is_active' => 'yes',
                    'is_self_step_category' => 'no',
                    'is_pass' => 'no',
                    'need_delay' => 'no',
                    'delay_to' => 0,
                    'delay_reason' => '',
                    'affected_task' => implode(',', $taskList),
                ];
                $insertData[] = $tmp;
            }
        }
        $res = [];
        if (!empty($insertData)) {
            $res = model(DelayOrderTaskStepCategoryConfirmModel::class)->addAll($insertData);
        }
        return $res;
    }

    /**
     * 延期环节确认
     * @param $confirmData
     * @param int $userId
     * @return array|array[]
     * @throws Throwable
     */
    public function confirm($confirmData, int $userId)
    {
        $res = [
            'updated' => [],
            'next_updated' => [],
        ];
        $delayOrderTaskStepCategoryConfirmIdList = array_column($confirmData, 'id');
        $confirmData = array_column($confirmData, null, 'id');
        $waitConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->where(['id' => ['IN', $delayOrderTaskStepCategoryConfirmIdList]])
            ->select();
        $waitConfirmList = array_filter($waitConfirmList, function ($i) {
            return $i['is_active'] === 'yes';
        });
        if (empty($waitConfirmList)) {
            throw new LogicException('There is no content to be confirmed', ErrorCode::WAIT_CONFIRM_IS_EMPTY);
        }

        $delayOrderIdList = array_values(array_column($waitConfirmList, 'delay_order_id', 'delay_order_id'));

        $delayOrderList = model(DelayOrderModel::class)
            ->join('`user` u on u.id = delay_order.created_by')
            ->where(['delay_order.id' => ['IN', implode(',', $delayOrderIdList)]])
            ->field('u.name as created_by_name,delay_order.*')
            ->select();
        $delayOrderList = array_column($delayOrderList, null, 'id');

        $confirmFinishedDelayOrderIdList = [];
        $model = model(DelayOrderTaskStepCategoryConfirmModel::class);
        $model->startTrans();
        try {
            // 一、更新当前环节确认结果
            // 先更新确认结果
            $passed = [];
            $notPassed = [];
            $confirmedDelayStepCategoryWhere = [];
            foreach ($waitConfirmList as $waitConfirmItem) {
                $confirmDataItem = $confirmData[$waitConfirmItem['id']];
                $confirmDataItem['confirm_user_id'] = $userId;
                $confirmDataItem['confirm_at'] = time();
                $confirmDataItem['is_confirmed'] = 'yes';
                $confirmDataItem['is_active'] = 'no';

                // 没有选择延期 那么就是不需要延期
                if (empty($confirmDataItem['need_delay']) || $confirmDataItem['need_delay'] === 'no') {
                    $confirmDataItem['is_pass'] = 'no';
                }

                $res['updated'][] = $model->save($confirmDataItem);
                $confirmedDelayStepCategoryWhere[] = [
                    'delay_order_id' => $waitConfirmItem['delay_order_id'],
                    'step_category_id' => $waitConfirmItem['step_category_id'],
                ];
                if ($confirmDataItem['is_pass'] === 'yes') {
                    $passed[] = $waitConfirmItem;
                } else {
                    $notPassed[] = $waitConfirmItem;
                }
            }
            // 二、需要延期的，激活下一环节确认节点
            $stepCategoryConfirmedNo = [];
            $stepCategoryConfirmedPass = [];
            // 更新下一批需要确认的环节
            $delayOrderNextStepCategory = [];
            $nextConfirmStepCategoryList = [];
            if (!empty($passed)) {
                // 【标准任务】如果还有下游任务，追加该任务的下游任务确认
                list($nextConfirmStepCategoryList, $delayOrderNextStepCategory) = $this->handleNextStepCategoryConfirmList(array_column($passed, 'uuid'), $res);
                $nextConfirmStepCategoryListMapByDelayTaskId = array_column($nextConfirmStepCategoryList, null, 'delay_order_task_id');
                foreach ($passed as $passedItem) {
                    if (isset($nextConfirmStepCategoryListMapByDelayTaskId[$passedItem['delay_order_task_id']])) {
                        continue;
                    }
                    // 标记已经确认完的
                    $stepCategoryConfirmedPass[] = $passedItem['delay_order_task_id'];
                }
            }

            // 三、本环节不通过的，后续节点全部不通过，直接退出确认
            // 查询延期单 本环节确认情况
            $selfStepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
                ->where([
                    'delay_order_id' => ['IN', $delayOrderIdList],
                    'is_self_step_category' => 'yes',
                ])->select();
            $selfStepCategoryConfirmList = array_column($selfStepCategoryConfirmList, null, 'delay_order_task_id');
            // 没有通过的 后续都标记为已审核未通过
            if (!empty($notPassed)) {
                $allNeedClosedConfirmStepCategoryList = $model
                    ->where([
                        'delay_order_task_id' => ['IN', array_column($notPassed, 'delay_order_task_id')],
                        'is_confirmed' => 'no',
                    ])->order('delay_order_id asc,id asc')->select();
                if (!empty($allNeedClosedConfirmStepCategoryList)) {
                    $res['delay_order_task_step_category_confirm'][] = model(DelayOrderTaskStepCategoryConfirmModel::class)
                        ->where(['id' => ['IN', array_column($allNeedClosedConfirmStepCategoryList, 'id')]])
                        ->save(['is_confirmed' => 'yes']);
                }

                foreach ($notPassed as $notPassedItem) {
                    $selfStepCategoryConfirm = $selfStepCategoryConfirmList[$notPassedItem['delay_order_task_id']] ?? null;
                    if (empty($selfStepCategoryConfirm) || $selfStepCategoryConfirm['need_delay'] === 'no') {
                        $stepCategoryConfirmedNo[] = $selfStepCategoryConfirm['delay_order_task_id'];
                    } else {
                        $stepCategoryConfirmedPass[] = $selfStepCategoryConfirm['delay_order_task_id'];
                    }
                }
            }

            // 四、延期单完成情况检查
            // 查询出已确认的同环节的所有数据
            if (count($confirmedDelayStepCategoryWhere) == 1) {
                $confirmedDelayStepCategoryWhere = $confirmedDelayStepCategoryWhere[0];
            } else {
                $confirmedDelayStepCategoryWhere = [
                    [$confirmedDelayStepCategoryWhere],
                    '_logic' => 'OR',
                ];
            }

            // 检查确认状态 根据当前已经确认的环节和延期单来检查 同一个延期单同一个环节是否都确认完
            $confirmedDelayOrderTaskStepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
                ->where($confirmedDelayStepCategoryWhere)
                ->field("*,concat(delay_order_id,'#',step_category_id) uk")
                ->order('delay_order_id asc,id asc')
                ->select();
            $confirmedDelayOrderTaskStepCategoryConfirmList = array_group_by($confirmedDelayOrderTaskStepCategoryConfirmList, 'uk');

            // 检查是否全部确认完 以及是否存在未审核
            $delayOrderStepCategoryAllReviewed = [];
            $delayOrderStepCategoryAllReviewedPassedDelayOrderTaskIdList = [];
            foreach ($confirmedDelayOrderTaskStepCategoryConfirmList as $checkKey => $checkStepCategoryConfirmList) {
                list($delayOrderId, $stepCategoryId) = explode('#', $checkKey);
                $isAllReviewed = true;
                $checkedPassed = [];
                foreach ($checkStepCategoryConfirmList as $checkStepCategoryConfirmItem) {
                    if ($checkStepCategoryConfirmItem['is_confirmed'] === 'no') {
                        $isAllReviewed = false;
                        break;
                    }
                    if ($checkStepCategoryConfirmItem['is_pass'] == 'yes') {
                        $checkedPassed[] = $checkStepCategoryConfirmItem['delay_order_task_id'];
                    }
                }
                if ($isAllReviewed) {
                    $delayOrderStepCategoryAllReviewed[$delayOrderId] = $stepCategoryId;
                    $delayOrderStepCategoryAllReviewedPassedDelayOrderTaskIdList[$delayOrderId] = $checkedPassed;
                }
            }

            // 五、延期单通知、状态更新
            // 分组进行通知和审核结果更新
            foreach ($delayOrderStepCategoryAllReviewed as $delayOrderId => $stepCategoryId) {
                // 判定是否还存在下一个人,则通知下一个人, 否则拿到最后的结果去通知提交人
                if (!empty($delayOrderNextStepCategory[$delayOrderId])) {
                    $hookData = [
                        'type' => 'delay_order_confirm',
                        'data' => [
                            'delay_order' => $delayOrderList[$delayOrderId],
                            'creator_name' => $delayOrderList[$delayOrderId]['created_by_name'],
                            'step_category_id' => $delayOrderNextStepCategory[$delayOrderId],
                        ],
                    ];
                    Hook::listen('delay_order_created_after', $hookData);
                } else {
                    // 审核结束 分拣需要更新的数据
                    foreach ($delayOrderStepCategoryAllReviewedPassedDelayOrderTaskIdList[$delayOrderId] ?? [] as $allReviewDelayOrderTaskId) {
                        $selfStepCategoryConfirm = $selfStepCategoryConfirmList[$allReviewDelayOrderTaskId] ?? null;
                        if (empty($selfStepCategoryConfirm) || $selfStepCategoryConfirm['need_delay'] === 'no') {
                            $stepCategoryConfirmedNo[] = $selfStepCategoryConfirm['delay_order_task_id'];
                            $confirmFinishedDelayOrderIdList[] = $selfStepCategoryConfirm['delay_order_id'];
                        } else {
                            $stepCategoryConfirmedPass[] = $selfStepCategoryConfirm['delay_order_task_id'];
                        }
                    }
                }
            }

            // 修改延期单任务上的确认状态
            if (!empty($stepCategoryConfirmedNo)) {
                $res['delay_order_task'][] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $stepCategoryConfirmedNo]])
                    ->save(['step_category_confirmed' => 'no', 'confirm_status' => 'no', 'confirming_step_category_id' => 0]);
            }
            if (!empty($stepCategoryConfirmedPass)) {
                $res['delay_order_task'][] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $stepCategoryConfirmedPass]])
                    ->save(['step_category_confirmed' => 'yes', 'confirm_status' => 'producer_confirming', 'confirming_step_category_id' => 0]);
            }

            // 六、下游确认节点判断执行自动跳过
            // 存在下一个待审核 检查是否需要自动跳过没有任务的环节
            if (!empty($nextConfirmStepCategoryList)) {
                $this->checkNextStepCategoryConfirmNodeIsNeedConfirm($nextConfirmStepCategoryList);
            }
            $model->commit();
        } catch (Throwable $e) {
            $model->rollback();
            throw $e;
        }

        // 检查延期单的 状态
        if (!empty($delayOrderIdList)) {
            Client::send('delay_order_confirmed_check', build_queue_data_with_xu([
                'delay_order_id_list' => $delayOrderIdList,
                'user_id' => $userId,
            ]));
        }
        return $res;
    }


    /**
     * 获取项目ID
     * @param $param
     * @return int|mixed
     */
    public function getProjectId($param)
    {
        $projectId = $param['project_id'] ?? 0;
        if (empty($projectId)) {
            return 0;
        }

        $where = [];
        $where['id'] = $projectId;
        $where['type'] = ProjectModel::TYPE_OUTSOURCE;
        //查询是否外包项目
        $projectInfo = model(ProjectModel::class)->where($where)->field('id,type,belong_project_id')->find();
        if ($projectInfo) {
            $projectId = $projectInfo['belong_project_id'] ?? 0;
        }
        return $projectId;
    }

    /**
     * 延期单确认详情
     * @param $param
     * @param $page
     * @param int $userId
     * @return array|array[]
     */
    public function detailByDelayOrderId($param, $page, int $userId)
    {
        $res = [
            'rows' => [],
            'total' => 0,
            'step_category_list' => [],
        ];
        $isFirstPage = $page[0] == 1;
        $delayOrderTaskListFilter = $param['filter'] ?? [];
        $episodeId = $param['episode_id'] ?? 0;
        $projectId = $this->getProjectId($param);
        $waitForMeConfirm = $param['wait_for_me_confirm'] ?? 'no';
        $iAccessConfirm = $param['i_access_confirm'] ?? 'no';

        $taskNameSearch = $param['task_name'] ?? '';
        $orderBy = $param['order'] ?? 'task.order_str';
        if (!empty($param['delay_order_id'])) {
            $delayOrder = model(DelayOrderModel::class)->find($param['delay_order_id']);
            if (empty($delayOrder)) {
                throw new LogicException('delay order not found', ErrorCode::DELAY_ORDER_NOT_FOUND);
            }
            $delayOrderTaskListFilter[] = [
                'delay_order_task.delay_order_id' => $delayOrder['id'],
            ];
            $episodeId = $delayOrder['episode_id'];
            $projectId = $delayOrder['project_id'];
        }
        if ($episodeId > 0) {
            $delayOrderTaskListFilter[] = ['delay_order_task.episode_id' => $episodeId];
        }
        if ($projectId > 0) {
            $delayOrderTaskListFilter[] = ['delay_order_task.project_id' => $projectId];
        }
        if (!empty($taskNameSearch)) {
            $delayOrderTaskListFilter[] = [
                'entity.name' => $taskNameSearch,
                'task.name' => $taskNameSearch,
                '_logic' => 'or',
            ];
        }

        // 我能确认的环节
        $userCanConfirmStepCategoryIdList = ProjectStepCategoryConfirmConfigService::getInstance()
            ->getUserCanConfirmStepCategoryIdList(['GT', 0], $userId, 'delay', 'project_id,step_category_id');
        $userCanConfirmStepCategoryIdList = array_group_by($userCanConfirmStepCategoryIdList, 'project_id');
        $iCanConfirmStepCategoryIdList = [];
        foreach ($userCanConfirmStepCategoryIdList as $confirmProjectId => $config) {
            $iCanConfirmStepCategoryIdList[$confirmProjectId] = array_column($config, 'step_category_id');
        }
        //　我是制片
        $projectIdListProducer = model(ProjectMemberModel::class)
            ->where([
                'user_id' => $userId,
                'role_code' => 'executive_producer',
                'is_delete' => 0,
            ])
            ->field('project_id')
            ->select();
        $userProducerProjectIds = array_column($projectIdListProducer, 'project_id');

        if ($waitForMeConfirm === 'yes' || $iAccessConfirm === 'yes') {
            $iCanAccessProjectList = array_unique(array_merge(array_keys($iCanConfirmStepCategoryIdList), $userProducerProjectIds));
            if (empty($iCanAccessProjectList)) {
                return $res;
            }
            $stepCategoryFilter = [];
            foreach ($iCanAccessProjectList as $accessProjectId) {
                if ($projectId != $accessProjectId) {
                    continue;
                }
                if (in_array($accessProjectId, $userProducerProjectIds)) {
                    $stepCategoryFilter[] = [
                        'delay_order_task.project_id' => $accessProjectId,
                        'delay_order_task.confirm_status' => "producer_confirming",
                    ];
                }
                $tempFilter = [];
                if (!empty($iCanConfirmStepCategoryIdList[$accessProjectId] ?? [])) {
                    $tempFilter = [
                        'delay_order_task.project_id' => $accessProjectId,
                        'delay_order_task_step_category_confirm.step_category_id' => ['IN', $iCanConfirmStepCategoryIdList[$accessProjectId]],
                        'delay_order_task.confirm_status' => "step_category_confirming",
                    ];
                    if ($iAccessConfirm == 'yes') {
                        $tempFilter["delay_order_task_step_category_confirm.is_active"] = "yes";
                    }
                }
                if (!empty($tempFilter)) {
                    $stepCategoryFilter[] = $tempFilter;
                }
            }
            if (count($stepCategoryFilter) > 1) {
                $stepCategoryFilter['_logic'] = 'or';
            }
            if (!empty($stepCategoryFilter)) {
                $delayOrderTaskListFilter[] = $stepCategoryFilter;
            }
        }

        //通过延期记录ID查询---不需要再次查询
        if (!empty($param['delay_order_task_id'])) {
            $delayOrderTaskIdList = explode(',', $param['delay_order_task_id']);
        } else {
            $res['total'] = model(DelayOrderTaskModel::class)
                ->join('task on task.id = delay_order_task.task_id')
                ->join('entity on entity.id = task.entity_id', 'LEFT')
                ->join('module on module.id = entity.module_id', 'left')
                ->join('delay_order_task_step_category_confirm on delay_order_task_step_category_confirm.delay_order_task_id = delay_order_task.id', 'LEFT')
                ->where($delayOrderTaskListFilter)
                ->count('distinct delay_order_task.id');

            $delayOrderTaskIdList = model(DelayOrderTaskModel::class)
                ->join('task on task.id = delay_order_task.task_id')
                ->join('entity on entity.id = task.entity_id', 'LEFT')
                ->join('module on module.id = entity.module_id', 'left')
                ->join('delay_order_task_step_category_confirm on delay_order_task_step_category_confirm.delay_order_task_id = delay_order_task.id', 'LEFT')
                ->where($delayOrderTaskListFilter)
                ->field('delay_order_task.id')
                ->group('delay_order_task.id')
                ->page($page[0], $page[1])
                ->order($orderBy)
                ->column('id');

            if (empty($delayOrderTaskIdList)) {
                return $res;
            }
        }

        $delayOrderTaskListFilter = [
            'delay_order_task.id' => ['IN', $delayOrderTaskIdList],
        ];

        $delayOrderTaskFields = [
            'entity.id',
            'entity.name',
            'entity.code',
            'entity.module_id',
            'entity.initial_episode_code',
            'entity.showings_number',
            'entity.json',

            'task.id',
            'task.step_type',
            'task.step_id',
            'task.step_category_id',
            'task.name',
            'task.code',
            'task.json',

            'project.id',
            'project.name',

            'delay_order_task.id',
            'delay_order_task.delay_order_id',
            'delay_order_task.type',
            'delay_order_task.project_id',
            'delay_order_task.task_id',
            'delay_order_task.original_plan_time',
            'delay_order_task.plan_delivery_time',
            'delay_order_task.delay_time',
            'delay_order_task.abnormal_info',
            'delay_order_task.delay_reason',
            'delay_order_task.delay_reason_type',
            'delay_order_task.step_category_confirmed',
            'delay_order_task.manager_confirmed',
            'delay_order_task.confirm_status',
        ];
        $delayOrderTaskList = model(DelayOrderTaskModel::class)
            ->join('task on task.id = delay_order_task.task_id')
            ->join('entity on entity.id = task.entity_id', 'LEFT')
            ->join('project on task.project_id = project.id', 'LEFT')
            ->where($delayOrderTaskListFilter)
            ->field(build_complex_query_fields($delayOrderTaskFields, '__'))
            ->order($orderBy)
            ->select();
        $delayOrderTaskEntityIdList = array_column($delayOrderTaskList, 'entity__id');
        $delayOrderTaskEntityIdList = array_filter($delayOrderTaskEntityIdList, function ($i) {
            return intval($i) > 0;
        });
        $delayOrderTaskIdList = array_column($delayOrderTaskList, 'delay_order_task__id');
        $delayOrderTaskStepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->alias('dotscc')
            ->join('tag_relation on tag_relation.relation_id = dotscc.id and tag_relation.relation_type = ' . TagRelationModel::RELATION_TYPE_DELAY_STEP_CATEGORY_CONFIRM, 'left')
            ->join('tag on tag.id = tag_relation.tag_id', 'left')
            ->where(['dotscc.delay_order_task_id' => ['IN', implode(',', $delayOrderTaskIdList)]])
            ->order('dotscc.delay_order_task_id asc,id asc')
            ->field('dotscc.*, tag.id as tag_id, tag.name as tag_name')
            ->select();
        $stepCategoryIdList = array_unique(array_column($delayOrderTaskStepCategoryConfirmList, 'step_category_id'));

        $entityStepCategoryDeliveryTimeList = model(TaskModel::class)
            ->where([
                'entity_id' => ['IN', implode(',', $delayOrderTaskEntityIdList)],
                'step_type' => TaskModel::STEP_TYPE_STEP,
                'step_category_id' => ['IN', implode(',', $stepCategoryIdList)],
            ])->field("max(plan_delivery_time) delivery_time,concat(entity_id,'#',step_category_id) uk")
            ->group("entity_id, step_category_id")->select();

        $entityStepCategoryDeliveryTimeList = array_column($entityStepCategoryDeliveryTimeList, 'delivery_time', 'uk');

        $stepCategoryList = StepCategoryService::getInstance()->getList([], '*');
        $stepCategoryList = array_column($stepCategoryList, null, 'id');
        $stepList = StepService::getInstance()->getList([], '*');
        $stepList = array_column($stepList, null, 'id');

        // 环节延期确认统计
        $stepCategoryDelayCount = [];
        if ($isFirstPage && $episodeId > 0) {
            $delayCount = model(DelayOrderTaskModel::class)
                ->where([
                    'episode_id' => $episodeId,
                    'type' => ['IN', [DelayOrderTaskModel::TYPE_REQUEST_DELAY, DelayOrderTaskModel::TYPE_WORK_ORDER, DelayOrderTaskModel::TYPE_DOWNSTREAM_DELAY]],
                ])->group('type')
                ->field('type,step_category_id,count(distinct task_id) num')
                ->select();
            $delayCountGrouped = array_group_by($delayCount, 'step_category_id');
            foreach ($delayCountGrouped as $stepCategoryId => $delayCount) {
                $stepCategoryDelayCount[$stepCategoryId] = ['total' => 0, 'upstream' => 0, 'self' => 0];
                foreach ($delayCount as $delayCountItem) {
                    $stepCategoryDelayCount[$stepCategoryId]['total'] += $delayCountItem['num'];
                    if ($delayCountItem['type'] === DelayOrderTaskModel::TYPE_DOWNSTREAM_DELAY) {
                        $stepCategoryDelayCount[$stepCategoryId]['upstream'] += $delayCountItem['num'];
                    } else {
                        $stepCategoryDelayCount[$stepCategoryId]['self'] += $delayCountItem['num'];
                    }
                }
            }
        }

        $delayOrderTaskStepCategoryConfirmListGrouped = array_group_by($delayOrderTaskStepCategoryConfirmList, 'delay_order_task_id');
        unset($delayOrderTaskStepCategoryConfirmList);
        // 第一页 输出头部和统计给到前端
        $stepCategoryIdAdded = [];
        if ($isFirstPage) {
            foreach ($delayOrderTaskStepCategoryConfirmListGrouped as $delayOrderTaskId => $delayOrderTaskStepCategoryConfirmList) {
                foreach ($delayOrderTaskStepCategoryConfirmList as $delayOrderTaskStepCategoryConfirmItem) {
                    if (!isset($stepCategoryList[$delayOrderTaskStepCategoryConfirmItem['step_category_id']]) || in_array($delayOrderTaskStepCategoryConfirmItem['step_category_id'], $stepCategoryIdAdded)) {
                        continue;
                    }
                    $stepCategoryIdAdded[] = $delayOrderTaskStepCategoryConfirmItem['step_category_id'];
                    $stepCategory = $stepCategoryList[$delayOrderTaskStepCategoryConfirmItem['step_category_id']];
                    $stepCategory['total'] = 0;
                    $stepCategory['upstream'] = 0;
                    $stepCategory['self'] = 0;
                    if (isset($stepCategoryDelayCount[$stepCategory['id']])) {
                        $stepCategory['total'] = $stepCategoryDelayCount[$stepCategory['id']]['total'];
                        $stepCategory['upstream'] = $stepCategoryDelayCount[$stepCategory['id']]['upstream'];
                        $stepCategory['self'] = $stepCategoryDelayCount[$stepCategory['id']]['self'];
                    }
                    $res['step_category_list'][] = $stepCategory;
                }
            }
        }

        // 当前用户能确认的环节列表
//        $iCanConfirmStepCategoryIdList = ProjectStepCategoryConfirmConfigService::getInstance()
//            ->getUserCanConfirmStepCategoryIdList($projectId, $userId, 'delay');

        foreach ($delayOrderTaskList as &$delayOrderTask) {
            $delayOrderTask = separate_complex_query_data($delayOrderTask, '__');
            $delayOrderTask['step'] = $stepList[$delayOrderTask['task']['step_id']] ?? null;
            $delayOrderTask['step_category'] = $stepCategoryList[$delayOrderTask['task']['step_category_id']] ?? null;
            $delayOrderTask['task'] = CommonService::getFormatAttrData(model(TaskModel::class), $delayOrderTask['task']);
            $delayOrderTask['task'] = CommonService::appendJsonFields($delayOrderTask['task'], 'json');


            if (!empty($delayOrderTask['entity']['module_id'])) {
                $module = module_by_id($delayOrderTask['entity']['module_id']);
                request()->getModuleCode($module['code']);
                $delayOrderTask['entity'] = CommonService::getFormatAttrData(model(EntityModel::class), $delayOrderTask['entity']);
                $delayOrderTask['entity'] = CommonService::appendJsonFields($delayOrderTask['entity'], 'json');
            }

            $first = true;
            foreach ($delayOrderTaskStepCategoryConfirmListGrouped[$delayOrderTask['delay_order_task']['id']] ?? [] as $delayOrderTaskStepCategoryConfirm) {
                if (!isset($stepCategoryList[$delayOrderTaskStepCategoryConfirm['step_category_id']])) {
                    continue;
                }
                if ($first) {
                    $first = false;
                    $delayOrderTaskStepCategoryConfirm['type'] = $delayOrderTask['delay_order_task']['type'];
                    $delayOrderTaskStepCategoryConfirm['original_plan_time'] = $delayOrderTask['delay_order_task']['original_plan_time'];
                    $delayOrderTaskStepCategoryConfirm['plan_delivery_time'] = $delayOrderTask['delay_order_task']['plan_delivery_time'];
                    $delayOrderTaskStepCategoryConfirm['delay_time'] = $delayOrderTask['delay_order_task']['delay_time'];
                    $delayOrderTaskStepCategoryConfirm['abnormal_info'] = $delayOrderTask['delay_order_task']['abnormal_info'];
                    $delayOrderTaskStepCategoryConfirm['delay_reason'] = $delayOrderTask['delay_order_task']['delay_reason'];
                }
                $stepCategory = $stepCategoryList[$delayOrderTaskStepCategoryConfirm['step_category_id']];
                $delayOrderTaskStepCategoryConfirm['current_user_can_confirm'] = false;
                // 是我能确认的环节并且当前环节是激活的
                if (in_array($stepCategory['id'], $iCanConfirmStepCategoryIdList[$delayOrderTask['delay_order_task']['project_id']] ?? []) &&
                    $delayOrderTaskStepCategoryConfirm['is_active'] === 'yes'
                ) {
                    $delayOrderTaskStepCategoryConfirm['current_user_can_confirm'] = true;
                }
                // 补充当前的计划交付时间
                $uk = sprintf("%d#%d", $delayOrderTask['entity']['id'] ?? 0, $stepCategory['id']);
                $delayOrderTaskStepCategoryConfirm['entity_step_category_plan_delivery_time'] = $entityStepCategoryDeliveryTimeList[$uk] ?? 0;
                $delayOrderTask[$stepCategory['code']] = $delayOrderTaskStepCategoryConfirm;
            }
        }
        $res['rows'] = $delayOrderTaskList;
        return $res;
    }

    /**
     * 延期单任务延期时间更新
     * 确认环节添加延期记录
     * @param $delayOrderTaskIdList
     * @return array
     * @throws \think\Exception
     */
    public function delayRequestDelayOrderTask($delayOrderTaskIdList)
    {
        $res = [];
        //比较最大时间是否超出计划的时间,否则就需要更改计划的时间
        $delayOrderTaskList = model(DelayOrderTaskModel::class)->where(['id' => ['IN', $delayOrderTaskIdList]])->select();
        $delayOrderTaskListByDelayOrderTaskId = array_column($delayOrderTaskList, null, 'id');
        $delayOrderTaskList = array_column($delayOrderTaskList, null, 'task_id');
        $taskIdList = array_keys($delayOrderTaskList);
        $taskFields = [
            "concat(entity_id,'#',step_category_id) uk",
            "id",
            "project_id",
            "plan_end_time",
            "plan_delivery_time",
            "entity_id",
            "episode_id",
            "step_category_id",
            "json->>'$.task_delay_sum' as task_delay_sum",
        ];
        $taskList = model(TaskModel::class)
            ->where(['id' => ['IN', $taskIdList]])
            ->field($taskFields)
            ->select();
        $taskList = array_column($taskList, null, 'id');
        $stepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->where([
                'delay_order_task_id' => ['IN', $delayOrderTaskIdList],
            ])
            ->select();
        $selfStepCategoryConfirmList = [];
        $entityStepCategoryFilter = [];
        $entityStepCategoryDelayTo = [];
        // 比对出需要延期的和添加延期记录的
        foreach ($stepCategoryConfirmList as $stepCategoryConfirm) {
            if ($stepCategoryConfirm['is_self_step_category'] === 'yes') {
                $selfStepCategoryConfirmList[$stepCategoryConfirm['delay_order_task_id']] = $stepCategoryConfirm;
            } elseif ($stepCategoryConfirm['need_delay'] === 'yes' && $stepCategoryConfirm['delay_to'] > 0) {
                $delayOrderTask = $delayOrderTaskListByDelayOrderTaskId[$stepCategoryConfirm['delay_order_task_id']];
                $task = $taskList[$delayOrderTask['task_id']];
                $entityStepCategoryFilter[] = [
                    'entity_id' => $task['entity_id'],
                    'step_category_id' => $stepCategoryConfirm['step_category_id'],
                ];
                $uk = sprintf("%d#%d", $task['entity_id'], $stepCategoryConfirm['step_category_id']);
                // 添加影响来源任务id
                $entityStepCategoryDelayTo[$uk] = array_merge($stepCategoryConfirm, ['affected_by_task_id' => $task['id']]);
            }
        }

        $entityStepCategoryTaskList = [];
        if (!empty($entityStepCategoryFilter)) {
            if (count($entityStepCategoryFilter) > 1) {
                $entityStepCategoryFilter['_logic'] = 'OR';
                $entityStepCategoryFilter = [$entityStepCategoryFilter];
            } else {
                $entityStepCategoryFilter = $entityStepCategoryFilter[0];
            }
            $entityStepCategoryTaskList = model(TaskModel::class)
                ->where(['step_type' => TaskModel::STEP_TYPE_STEP])
                ->where($entityStepCategoryFilter)
                ->field($taskFields)
                ->select();
        }

        $delayOrderTaskInsertList = [];
        $updateTaskList = [];
        // 延期单其他环节标识延期记录
        foreach ($entityStepCategoryTaskList as $task) {
            $delayData = $entityStepCategoryDelayTo[$task['uk']];
            $delayTime = $delayData['delay_to'];
            $updateTaskTmp = [
                'id' => $task['id'],
                'plan_end_time' => date("Y-m-d H:i:s", $delayTime),
                'task_delay_sum' => ($task['task_delay_sum'] ?? 0) + 1,
            ];
            //如果超过了交付时间要更改交付时间
            if ($delayTime > $task['plan_delivery_time']) {
                $updateTaskTmp['plan_delivery_time'] = $delayTime;
            }
            $updateTaskList[] = $updateTaskTmp;
            $delayOrderTaskInsertList[] = [
                'type' => DelayOrderTaskModel::TYPE_DOWNSTREAM_DELAY,
                'project_id' => $task['project_id'],
                'task_id' => $task['id'],
                'original_plan_time' => $task['plan_end_time'],
                'plan_delivery_time' => $task['plan_delivery_time'],
                'delay_time' => $delayTime,
                'abnormal_info' => '延期下游同时延期',
                'delay_reason' => $delayData['delay_reason'],
                'created_by' => fill_created_by(),
                'created' => time(),
                'uuid' => create_uuid(),
                'step_category_id' => $task['step_category_id'],
                'episode_id' => $task['episode_id'],
                'step_category_confirmed' => 'yes',
                'manager_confirmed' => 'yes',
                'confirm_status' => 'yes',
                'manager_confirm_user_id' => 0,
                'affected_by_task' => $delayData['affected_by_task_id'],
            ];
        }

        foreach ($taskList as $task) {
            $delayOrderTask = $delayOrderTaskList[$task['id']];
            $delayOrderTaskSelfStepCategoryConfirm = $selfStepCategoryConfirmList[$delayOrderTask['id']] ?? null;
            if (empty($delayOrderTaskSelfStepCategoryConfirm)) {
                continue;
            }
            // 判断环节确认的时候 是否修改过异常处理方案
            if ($delayOrderTaskSelfStepCategoryConfirm['is_confirmed'] === 'yes') {
                // 标记为不需要延期 就跳过
                if ($delayOrderTaskSelfStepCategoryConfirm['need_delay'] === 'no') {
                    continue;
                }
                // 重置延期到的时间
                $delayTime = $delayOrderTaskSelfStepCategoryConfirm['delay_to'];
            } else {
                $delayTime = $delayOrderTask['delay_time'];
            }
            $updateTaskTmp = [
                'id' => $task['id'],
                'plan_end_time' => date("Y-m-d H:i:s", $delayTime),
                'task_delay_sum' => ($task['task_delay_sum'] ?? 0) + 1,
            ];
            //如果超过了交付时间要更改交付时间
            if ($delayTime > $delayOrderTask['plan_delivery_time']) {
                $updateTaskTmp['plan_delivery_time'] = $delayTime;
            }
            $updateTaskList[] = $updateTaskTmp;
        }
        if (empty($updateTaskList)) {
            return $res;
        }
        // 更改任务时间
        $res['task_updated'] = CommonService::instance("task")
            ->commonBatchUpdate($updateTaskList, module_by_code('task'), false);
        // 批量添加下游任务延期任务记录
        if (!empty($delayOrderTaskInsertList)) {
            $res['delay_order_task_added'] = model(DelayOrderTaskModel::class)->addAll($delayOrderTaskInsertList);
        }
        return $res;
    }


    /**
     *  标准任务延期单任务延期时间更新
     * @param $delayOrderTaskIdList
     * @return array
     * @throws \think\Exception
     */
    public function delayStandardRequestDelayOrderTask($delayOrderTaskIdList)
    {
        $res = [];
        // 1. 通过延期单id,找到所有的确定记录
        $standardTaskConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->join('delay_order_task on delay_order_task.id = delay_order_task_step_category_confirm.delay_order_task_id')
            ->where([
                'delay_order_task_step_category_confirm.delay_order_task_id' => ['IN', $delayOrderTaskIdList],
                'delay_order_task_step_category_confirm.is_pass' => 'yes',
                'delay_order_task_step_category_confirm.need_delay' => 'yes',
            ])
            ->field([
                'delay_order_task_step_category_confirm.*',
                'delay_order_task.task_id as delay_order_task_task_id',
            ])
            ->select();
        $delayTo = [];
        $taskIdList = [];
        foreach ($standardTaskConfirmList as $confirmDelayItem) {
            if (empty($confirmDelayItem['affected_task'])) {
                if ($confirmDelayItem['is_self_step_category'] == 'no') {
                    continue;
                }
                $confirmDelayItem['affected_task'] = $confirmDelayItem['delay_order_task_task_id'];
            }
            $delayTo = array_replace($delayTo, array_fill_keys(
                explode(',', $confirmDelayItem['affected_task']),
                $confirmDelayItem['delay_to']
            ));
            $taskIdList[] = explode(',', $confirmDelayItem['affected_task']);
        }
        $taskIdList = array_unique(array_merge(...array_values($taskIdList)));
        if (empty($taskIdList)) {
            return $res;
        }
        $taskFields = [
            "id",
            "project_id",
            "plan_end_time",
            "plan_delivery_time",
            "episode_id",
            "step_category_id",
            "json->>'$.task_delay_sum' as task_delay_sum",
        ];
        $taskList = model(TaskModel::class)
            ->where(['id' => ['IN', $taskIdList]])
            ->field($taskFields)
            ->select();
        if (empty($taskList)) {
            return $res;
        }
        $updateTaskList = [];
        foreach ($taskList as $task) {
            $delayTime = $delayTo[$task['id']] ?? 0;
            // 如果延期时间，少于当前任务计划完成时间,就不做更改
            $taskPlanEndTime = $task['plan_end_time'] ?? 0;
            if ($delayTime <= $taskPlanEndTime) {
                continue;
            }
            $updateTaskTmp = [
                'id' => $task['id'],
                'plan_end_time' => date("Y-m-d H:i:s", $delayTime),
                'task_delay_sum' => ($task['task_delay_sum'] ?? 0) + 1,
            ];
            //如果超过了交付时间要更改交付时间
            if ($delayTime > $task['plan_delivery_time']) {
                $updateTaskTmp['plan_delivery_time'] = $delayTime;
            }
            $updateTaskList[] = $updateTaskTmp;
        }
        if (empty($updateTaskList)) {
            return $res;
        }
        //  3.更新任务,按照已确认的时间，更新任务计划完成时间和计划交付时间
        $res['task_updated'] = CommonService::instance("task")
            ->commonBatchUpdate($updateTaskList, module_by_code('task'), false);
        return $res;
    }

    /**
     * 管理确认
     * @param $dataList
     * @param int $userId
     * @return array
     * @throws Throwable
     * @throws \think\Exception
     */
    public function managerConfirm($dataList, int $userId)
    {
        $res = [];
        $delayOrderTaskIdList = array_column($dataList, 'id');
        $delayOrderTaskList = model(DelayOrderTaskModel::class)
            ->join('task on task.id = delay_order_task.task_id')
            ->where(['delay_order_task.id' => ['IN', $delayOrderTaskIdList]])
            ->field(
                [
                    'delay_order_task.*',
                    'task.step_type as task_step_type'
                ]
            )
            ->select();
        if (empty($delayOrderTaskList)) {
            return $res;
        }
        $delayOrderIdList = array_values(array_column($delayOrderTaskList, 'delay_order_id', 'delay_order_id'));
        $delayOrderTaskStepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->where(['delay_order_task_id' => ['IN', $delayOrderTaskIdList]])
            ->order('delay_order_task_id asc,id asc')
            ->select();

        $delayOrderTaskList = array_column($delayOrderTaskList, null, 'id');
        $updatePass = [];
        $updateNo = [];
        foreach ($dataList as $data) {
            $delayOrderTask = $delayOrderTaskList[$data['id']] ?? null;
            if (empty($delayOrderTask)) {
                continue;
            }
            // 只有待制片确认可以进行确认
            if ($delayOrderTask['confirm_status'] !== 'producer_confirming') {
                continue;
            }
            // 工序任务
            if ($delayOrderTask['task_step_type'] == TaskModel::STEP_TYPE_STEP) {
                if ($data['is_pass'] === 'yes') {
                    $updatePass[] = $data['id'];
                } else {
                    $updateNo[] = $data['id'];
                }
            }
            // 标准任务
            if (in_array($delayOrderTask['task_step_type'], [TaskModel::STEP_TYPE_TO_DO, TaskModel::STEP_TYPE_STANDARD_MEETING, TaskModel::STEP_TYPE_STANDARD_REVIEW, TaskModel::STEP_TYPE_STANDARD_MAKE_TO_DO])) {
                if ($data['is_pass'] === 'yes') {
                    $standardUpdatePass[] = $data['id'];
                } else {
                    $standardUpdateNo[] = $data['id'];
                }
            }
        }
        if (empty($updatePass) && empty($updateNo) && empty($standardUpdatePass) && empty($standardUpdateNo)) {
            Client::send('delay_order_confirmed_check', build_queue_data_with_xu([
                'delay_order_id_list' => $delayOrderIdList,
                'user_id' => $userId,
            ]));
            throw new LogicException('There is no content to be confirmed', ErrorCode::WAIT_CONFIRM_IS_EMPTY);
        }

        $updateDelayActiveToNo = [];
        $delayOrderTaskConfirmed = [
            'yes' => [],
            'no' => [],
        ];
        // 检查环节的需要延期的状态  只要有一个需要延期 那么这个延期任务就是已经有一个环节或以上确认的
        $delayOrderTaskStepCategoryConfirmListGrouped = array_group_by($delayOrderTaskStepCategoryConfirmList, 'delay_order_task_id');
        foreach ($delayOrderTaskStepCategoryConfirmListGrouped as $delayOrderTaskId => $delayOrderTaskStepCategoryConfirmList) {
            $confirmed = 'no';
            $delayOrderTask = $delayOrderTaskList[$delayOrderTaskId];
            if ($delayOrderTask['step_category_confirmed'] !== 'default') {
                continue;
            }
            foreach ($delayOrderTaskStepCategoryConfirmList as $delayOrderTaskStepCategoryConfirm) {
                if ($delayOrderTaskStepCategoryConfirm['need_delay'] === 'yes') {
                    $confirmed = 'yes';
                }
                if ($delayOrderTaskStepCategoryConfirm['is_active'] === 'yes') {
                    $updateDelayActiveToNo[] = $delayOrderTaskStepCategoryConfirm['id'];
                }
            }
            $delayOrderTaskConfirmed[$confirmed][] = $delayOrderTaskId;
        }

        model(DelayOrderTaskModel::class)->startTrans();
        try {
            // 更新确认中的状态为结束
            if (!empty($updateDelayActiveToNo)) {
                $res['update_confirm_active'] = model(DelayOrderTaskStepCategoryConfirmModel::class)
                    ->where(['id' => ['IN', $updateDelayActiveToNo]])
                    ->save(['is_active' => 'no']);
            }
            // 更新环节的确认状态结果
            foreach ($delayOrderTaskConfirmed as $updateTo => $confirmIdList) {
                if (!in_array($updateTo, ['yes', 'no']) || empty($confirmIdList)) {
                    continue;
                }
                $res['delay_order_task_step_category_confirm:' . $updateTo] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $confirmIdList]])
                    ->save([
                        'step_category_confirmed' => $updateTo,
                    ]);
            }
            // -----------------------------------------[工序任务]---------------------------------------------------start
            if (!empty($updateNo)) {
                $res['no'] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $updateNo]])
                    ->save([
                        'manager_confirmed' => 'no',
                        'manager_confirm_user_id' => $userId,
                        'confirm_status' => 'no',
                    ]);
            }
            if (!empty($updatePass)) {
                $res['yes'] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $updatePass]])
                    ->save([
                        'manager_confirmed' => 'yes',
                        'manager_confirm_user_id' => $userId,
                        'confirm_status' => 'yes',
                    ]);
                $res['task_update'] = $this->delayRequestDelayOrderTask($updatePass);
            }
            // -----------------------------------------[工序任务]---------------------------------------------------end

            // -----------------------------------------[标准任务]----------------------------------------------------start
            if (!empty($standardUpdateNo)) {
                $res['no'] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $standardUpdateNo]])
                    ->save([
                        'manager_confirmed' => 'no',
                        'manager_confirm_user_id' => $userId,
                        'confirm_status' => 'no',
                    ]);
            }
            if (!empty($standardUpdatePass)) {
                $res['yes'] = model(DelayOrderTaskModel::class)
                    ->where(['id' => ['IN', $standardUpdatePass]])
                    ->save([
                        'manager_confirmed' => 'yes',
                        'manager_confirm_user_id' => $userId,
                        'confirm_status' => 'yes',
                    ]);
                $res['task_update'] = $this->delayStandardRequestDelayOrderTask($standardUpdatePass);
            }
            // -----------------------------------------[标准任务]-----------------------------------------------------end
            model(DelayOrderTaskModel::class)->commit();
        } catch (Throwable $e) {
            model(DelayOrderTaskModel::class)->rollback();
            throw $e;
        }

        if (!empty($delayOrderIdList)) {
            Client::send('delay_order_confirmed_check', build_queue_data_with_xu([
                'delay_order_id_list' => $delayOrderIdList,
                'user_id' => $userId,
            ]));
        }

        return $res;
    }

    /**
     * 检查延期单是否都确认完毕
     * @param array $delayOrderIdList
     * @param int $userId
     * @return void
     * @throws Exception
     */
    public function checkDelayOrderAllConfirmed(array $delayOrderIdList, int $userId)
    {
        $confirmUser = model(UserModel::class)->find($userId);
        $delayOrderList = model(DelayOrderModel::class)->where(['id' => ['IN', implode(',', $delayOrderIdList)]])->select();
        $delayOrderList = array_column($delayOrderList, null, 'id');
        $delayOrderTaskListAll = model(DelayOrderTaskModel::class)
            ->where([
                'delay_order_id' => ['IN', implode(',', $delayOrderIdList)],
                'type' => ['in', [DelayOrderTaskModel::TYPE_REQUEST_DELAY, DelayOrderTaskModel::TYPE_WORK_ORDER]]
            ])
            ->select();
        $delayOrderTaskListAllGrouped = array_group_by($delayOrderTaskListAll, 'delay_order_id');
        foreach ($delayOrderList as $delayOrder) {
            $delayOrderTaskListAll = $delayOrderTaskListAllGrouped[$delayOrder['id']] ?? [];
            $delayTotal = 0;
            $managerConfirmed = 0;
            $managerPassed = 0;
            $confirmingScore = [
                DelayOrderTaskModel::CONFIRM_STATUS_STEP_CATEGORY_CONFIRMING => 0,
                DelayOrderTaskModel::CONFIRM_STATUS_PRODUCER_CONFIRMING => 0,
            ];
            foreach ($delayOrderTaskListAll as $delayOrderTask) {
                $delayTotal += 1;
                if ($delayOrderTask['confirm_status'] == DelayOrderTaskModel::CONFIRM_STATUS_YES) {
                    $managerConfirmed += 1;
                    $managerPassed += 1;
                } elseif ($delayOrderTask['confirm_status'] == DelayOrderTaskModel::CONFIRM_STATUS_NO) {
                    $managerConfirmed += 1;
                }

                if (in_array($delayOrderTask['confirm_status'], [
                    DelayOrderTaskModel::CONFIRM_STATUS_STEP_CATEGORY_CONFIRMING,
                    DelayOrderTaskModel::CONFIRM_STATUS_PRODUCER_CONFIRMING,
                ])) {
                    $confirmingScore[$delayOrderTask['confirm_status']] += 1;
                }
            }
            // 检查现在还在确认中的状态
            $confirmingStatus = null;
            foreach ([DelayOrderTaskModel::CONFIRM_STATUS_STEP_CATEGORY_CONFIRMING, DelayOrderTaskModel::CONFIRM_STATUS_PRODUCER_CONFIRMING] as $confirmStatusType) {
                if ($confirmingScore[$confirmStatusType] > 0) {
                    $confirmingStatus = $confirmStatusType;
                    break;
                }
            }
            $delayOrderUpdateData = [];
            $reviewFirstFinished = false;
            if ($delayTotal == $managerConfirmed && $delayOrder['is_reviewed'] != 'yes') {
                $delayOrderUpdateData['is_reviewed'] = 'yes';
                $reviewFirstFinished = true;
                $confirmingStatus = $managerConfirmed === $managerPassed ? 'yes' : 'no';
            } elseif ($delayTotal == $managerConfirmed) {
                $confirmingStatus = $managerConfirmed === $managerPassed ? 'yes' : 'no';
            }
            if (!empty($confirmingStatus) && $confirmingStatus != $delayOrder['confirm_status']) {
                $delayOrderUpdateData['confirm_status'] = $confirmingStatus;
            }

            if (!empty($delayOrderUpdateData)) {
                // 修改延期单
                $delayOrderUpdateData['id'] = $delayOrder['id'];
                model(DelayOrderModel::class)->modifyItem($delayOrderUpdateData);
            }
            if ($reviewFirstFinished) {
                $hookData = [
                    'type' => 'delay_order_result',
                    'data' => [
                        'is_pass' => $managerConfirmed === $managerPassed,
                        'review_names' => [$confirmUser['name']],
                        'reviewed' => time(),
                        'delay_order' => $delayOrder,
                    ],
                ];
                Hook::listen('delay_order_created_after', $hookData);
            }
        }
    }

    /**
     * 延期任务列表
     * @param $param
     * @param $page
     * @param int $userId
     * @return array|array[]
     */
    public function delayTaskList($param, $page, int $userId)
    {
        $res = [
            'rows' => [],
        ];
        $delayOrderTaskListFilter = $param['filter'] ?? [];
        $episodeId = $param['episode_id'] ?? 0;
        $projectId = $param['project_id'] ?? 0;
        $taskNameSearch = $param['task_name'] ?? '';
        $selfTask = $param['self_task'] ?? 'no';
        $confirmStatus = $param['confirm_status'] ?? '';
        if (!empty($param['delay_order_id'])) {
            $delayOrder = model(DelayOrderModel::class)->find($param['delay_order_id']);
            if (empty($delayOrder)) {
                throw new LogicException('delay order not found', ErrorCode::DELAY_ORDER_NOT_FOUND);
            }
            $delayOrderTaskListFilter[] = [
                'delay_order_task.delay_order_id' => $delayOrder['id'],
            ];
            $episodeId = $delayOrder['episode_id'];
            $projectId = $delayOrder['project_id'];
        }
        if (!empty($episodeId)) {
            $delayOrderTaskListFilter[] = ['delay_order_task.episode_id' => $episodeId];
        }
        if ($projectId > 0) {
            $delayOrderTaskListFilter[] = ['delay_order_task.project_id' => $projectId];
        }
        if ($selfTask === 'yes') {
            $delayOrderTaskListFilter[] = ['delay_order_task.created_by' => $userId];
        }
        if (!empty($taskNameSearch)) {
            $delayOrderTaskListFilter[] = [
                'entity.name' => $taskNameSearch,
                'task.name' => $taskNameSearch,
                '_logic' => 'or',
            ];
        }

        switch ($confirmStatus) {
            case 'step_category':
                $delayOrderTaskListFilter[] = [
                    'delay_order_task.manager_confirmed' => 'default',
                    'delay_order_task.step_category_confirmed' => 'default',
                ];
                break;
            case 'producer':
                $delayOrderTaskListFilter[] = [
                    'delay_order_task.manager_confirmed' => 'default',
                    'delay_order_task.step_category_confirmed' => ['IN', ['yes', 'no']],
                ];
                break;
            case 'confirmed':
                $delayOrderTaskListFilter[] = [
                    'delay_order_task.manager_confirmed' => ['IN', ['yes', 'no']],
                ];
                break;
        }


        $delayOrderTaskIdList = model(DelayOrderTaskModel::class)
            ->join('task on task.id = delay_order_task.task_id')
            ->join('entity on entity.id = task.entity_id', 'LEFT')
            ->join('delay_order_task_step_category_confirm on delay_order_task_step_category_confirm.delay_order_task_id = delay_order_task.id', 'LEFT')
            ->where($delayOrderTaskListFilter)
            ->field('delay_order_task.id')
            ->group('delay_order_task.id')
            ->page($page[0], $page[1])
            ->order('task.order_str')
            ->column('id');

        if (empty($delayOrderTaskIdList)) {
            return $res;
        }

        $delayOrderTaskListFilter = [
            'delay_order_task.id' => ['IN', $delayOrderTaskIdList],
        ];

        $delayOrderTaskFields = [
            'entity.id',
            'entity.name',
            'entity.code',
            'entity.module_id',
            'entity.initial_episode_code',
            'entity.showings_number',
            'entity.json',

            'task.id',
            'task.step_type',
            'task.step_id',
            'task.step_category_id',
            'task.name',
            'task.code',
            'task.json',

            'delay_order_task.id',
            'delay_order_task.delay_order_id',
            'delay_order_task.type',
            'delay_order_task.project_id',
            'delay_order_task.task_id',
            'delay_order_task.original_plan_time',
            'delay_order_task.plan_delivery_time',
            'delay_order_task.delay_time',
            'delay_order_task.abnormal_info',
            'delay_order_task.delay_reason',
            'delay_order_task.step_category_confirmed',
            'delay_order_task.manager_confirmed',
        ];
        $delayOrderTaskList = model(DelayOrderTaskModel::class)
            ->join('task on task.id = delay_order_task.task_id')
            ->join('entity on entity.id = task.entity_id', 'LEFT')
            ->where($delayOrderTaskListFilter)
            ->field(build_complex_query_fields($delayOrderTaskFields, '__'))
            ->select();
        $delayOrderTaskEntityIdList = array_column($delayOrderTaskList, 'entity__id');
        $delayOrderTaskEntityIdList = array_filter($delayOrderTaskEntityIdList, function ($i) {
            return intval($i) > 0;
        });
        $delayOrderTaskIdList = array_column($delayOrderTaskList, 'delay_order_task__id');
        $taskIdList = array_column($delayOrderTaskList, 'task__id', 'task__id');
        $taskRelationTagList = model(TaskRelationTagModel::class)
            ->where(['task_id' => ['IN', implode(',', $taskIdList)]])
            ->where(['link_module_code' => ['IN', ['step_category', 'show_step_category']]])
            ->select();
        $taskRelationTagList = array_column($taskRelationTagList, 'link_id', 'task_id');

        $delayOrderTaskStepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->where(['delay_order_task_id' => ['IN', implode(',', $delayOrderTaskIdList)]])
            ->order('delay_order_task_id asc,id asc')
            ->select();
        $stepCategoryIdList = array_unique(array_column($delayOrderTaskStepCategoryConfirmList, 'step_category_id'));

        $entityStepCategoryDeliveryTimeList = model(TaskModel::class)
            ->where([
                'entity_id' => ['IN', implode(',', $delayOrderTaskEntityIdList)],
                'step_type' => TaskModel::STEP_TYPE_STEP,
                'step_category_id' => ['IN', implode(',', $stepCategoryIdList)],
            ])->field("max(plan_delivery_time) delivery_time,concat(entity_id,'#',step_category_id) uk")
            ->group("entity_id, step_category_id")->select();

        $entityStepCategoryDeliveryTimeList = array_column($entityStepCategoryDeliveryTimeList, 'delivery_time', 'uk');

        $stepCategoryList = StepCategoryService::getInstance()->getList([], 'id,name,code,color');
        $stepCategoryList = array_column($stepCategoryList, null, 'id');
        $stepList = StepService::getInstance()->getList([], 'id,name,code,color,step_category_id');
        $stepList = array_column($stepList, null, 'id');

        $delayOrderTaskStepCategoryConfirmListGrouped = array_group_by($delayOrderTaskStepCategoryConfirmList, 'delay_order_task_id');
        unset($delayOrderTaskStepCategoryConfirmList);

        foreach ($delayOrderTaskList as &$delayOrderTask) {
            $delayOrderTask = separate_complex_query_data($delayOrderTask, '__');
            $delayOrderTask['step'] = $stepList[$delayOrderTask['task']['step_id']] ?? null;

            if ($delayOrderTask['task']['step_category_id'] <= 0) {
                $delayOrderTask['task']['step_category_id'] = $taskRelationTagList[$delayOrderTask['task']['id']] ?? 0;
            }
            $delayOrderTask['step_category'] = $stepCategoryList[$delayOrderTask['task']['step_category_id']] ?? null;

            $delayOrderTask['task'] = CommonService::getFormatAttrData(model(TaskModel::class), $delayOrderTask['task']);
            $delayOrderTask['task'] = CommonService::appendJsonFields($delayOrderTask['task'], 'json');

            if (!empty($delayOrderTask['entity']['module_id'])) {
                $module = module_by_id($delayOrderTask['entity']['module_id']);
                request()->getModuleCode($module['code']);
                $delayOrderTask['entity'] = CommonService::getFormatAttrData(model(EntityModel::class), $delayOrderTask['entity']);
                $delayOrderTask['entity'] = CommonService::appendJsonFields($delayOrderTask['entity'], 'json');
            }

            $first = true;
            foreach ($delayOrderTaskStepCategoryConfirmListGrouped[$delayOrderTask['delay_order_task']['id']] ?? [] as $delayOrderTaskStepCategoryConfirm) {
                if (!isset($stepCategoryList[$delayOrderTaskStepCategoryConfirm['step_category_id']])) {
                    continue;
                }
                if ($first) {
                    $first = false;
                    $delayOrderTaskStepCategoryConfirm['type'] = $delayOrderTask['delay_order_task']['type'];
                    $delayOrderTaskStepCategoryConfirm['original_plan_time'] = $delayOrderTask['delay_order_task']['original_plan_time'];
                    $delayOrderTaskStepCategoryConfirm['plan_delivery_time'] = $delayOrderTask['delay_order_task']['plan_delivery_time'];
                    $delayOrderTaskStepCategoryConfirm['delay_time'] = $delayOrderTask['delay_order_task']['delay_time'];
                    $delayOrderTaskStepCategoryConfirm['abnormal_info'] = $delayOrderTask['delay_order_task']['abnormal_info'];
                    $delayOrderTaskStepCategoryConfirm['delay_reason'] = $delayOrderTask['delay_order_task']['delay_reason'];
                }
                $stepCategory = $stepCategoryList[$delayOrderTaskStepCategoryConfirm['step_category_id']];
                $delayOrderTaskStepCategoryConfirm['current_user_can_confirm'] = false;
                // 补充当前的计划交付时间
                $uk = sprintf("%d#%d", $delayOrderTask['entity']['id'] ?? 0, $stepCategory['id']);
                $delayOrderTaskStepCategoryConfirm['entity_step_category_plan_delivery_time'] = $entityStepCategoryDeliveryTimeList[$uk] ?? 0;
                $delayOrderTaskStepCategoryConfirm['step_category'] = $stepCategoryList[$delayOrderTaskStepCategoryConfirm['step_category_id']];
                $delayOrderTask['step_category_confirm_list'][] = $delayOrderTaskStepCategoryConfirm;
            }
        }
        $res['rows'] = $delayOrderTaskList;
        return $res;
    }

    /**
     * 检查下一个节点是否需要确认
     * 1. 是否存在任务
     * 2. 任务是否被取消
     * @param $nextConfirmStepCategoryList
     * @return void
     */
    private function checkNextStepCategoryConfirmNodeIsNeedConfirm($nextConfirmStepCategoryList)
    {
        $delayOrderTaskList = model(DelayOrderTaskModel::class)
            ->join('task on task.id = delay_order_task.task_id')
            ->where(['delay_order_task.id' => ['IN', array_column($nextConfirmStepCategoryList, 'delay_order_task_id')]])
            ->field(
                'delay_order_task.id,task.source_entity_id'
                . ', task.step_type'
            )
            ->select();
        $taskStepType = [
            TaskModel::STEP_TYPE_STANDARD_MEETING,
            TaskModel::STEP_TYPE_STANDARD_REVIEW,
            TaskModel::STEP_TYPE_TO_DO,
            TaskModel::STEP_TYPE_STANDARD_MAKE_TO_DO,
        ];
        // 一、工序任务跳过判定
        // 取出标准任务单独判断
        $delayOrderTaskStandardIdList = [];
        // 拼接工序任务查询条件，查询工序任务数量，为空时自动确认
        $nextConfirmStepCategoryList = array_column($nextConfirmStepCategoryList, null, 'delay_order_task_id');
        $taskEntityStepCategoryFilter = [];
        $delayOrderTaskStepCategoryConfirmWithTaskRelation = [];
        foreach ($delayOrderTaskList as $delayOrderTask) {
            if (in_array($delayOrderTask['step_type'], $taskStepType)) {
                $delayOrderTaskStandardIdList[] = $delayOrderTask['id'];
                continue;
            }
            $stepCategoryId = $nextConfirmStepCategoryList[$delayOrderTask['id']]['step_category_id'];
            $taskEntityStepCategoryFilter[] = [
                'task.source_entity_id' => $delayOrderTask['source_entity_id'],
                'task.step_category_id' => $stepCategoryId,
            ];
            $delayOrderTaskStepCategoryConfirmWithTaskRelation[$nextConfirmStepCategoryList[$delayOrderTask['id']]['id']]
                = sprintf('%d-%d', $delayOrderTask['source_entity_id'], $stepCategoryId);
        }
        $closedStatus = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $filter = [
            'task.step_type' => TaskModel::STEP_TYPE_STEP,
            "task.json->>'$.task_status'" => ['NEQ', $closedStatus['id']],
        ];

        $needSkipData = [];
        if (!empty($taskEntityStepCategoryFilter)) {
            if (count($taskEntityStepCategoryFilter) > 1) {
                $taskEntityStepCategoryFilter['_logic'] = 'OR';
                $taskEntityStepCategoryFilter = [$taskEntityStepCategoryFilter];
            } else {
                $taskEntityStepCategoryFilter = $taskEntityStepCategoryFilter[0];
            }
            $filter[] = $taskEntityStepCategoryFilter;
            $taskList = model(TaskModel::class)->where($filter)
                ->group('source_entity_id,step_category_id')
                ->field("concat(source_entity_id,'-',step_category_id) uk")
                ->column('uk');
            // 检查没有任务 自动确认通过
            foreach ($delayOrderTaskStepCategoryConfirmWithTaskRelation as $delayOrderStepCategoryConfirmId => $uk) {
                if (in_array($uk, $taskList)) {
                    continue;
                }
                $needSkipData[] = [
                    'id' => $delayOrderStepCategoryConfirmId,
                    'is_pass' => 'yes',
                    'need_delay' => 'yes',
                    'delay_to' => 0,
                ];
            }


        }

        // 二、标准任务跳过判定
        // 查询有效任务
        $nextConfirmTaskStandardList = array_filter($nextConfirmStepCategoryList, fn($item) => in_array($item['delay_order_task_id'], $delayOrderTaskStandardIdList));
        $nextConfirmTaskStandardList = array_map(fn($item) => array_merge($item, ['affected_task' => split_array($item['affected_task'])]), $nextConfirmTaskStandardList);
        $nextConfirmTaskStandardIdList = array_merge(...array_column($nextConfirmTaskStandardList, 'affected_task'));
        if (!empty($nextConfirmTaskStandardIdList)) {
            $affectingTask = model(TaskModel::class)->where([
                'id' => ['in', $nextConfirmTaskStandardIdList],
                'json->>"$.task_status"' => ['not in', StatusService::getInstance()->byCodeMap(['closed', 'final'], false, 'id'),]
            ])->column('id');
            foreach ($nextConfirmTaskStandardList as $delayConfirmItem) {
                // 当前节点上挂的任务，无有效任务的，可自动确认
                if (empty(array_intersect($delayConfirmItem['affected_task'], $affectingTask))) {
                    $needSkipData[] = [
                        'id' => $delayConfirmItem['id'],
                        'is_pass' => 'yes',
                        'need_delay' => 'yes',
                        'delay_to' => 0,
                    ];
                }
            }
        }
        if (empty($needSkipData)) {
            return;
        }
        Client::send('delay_order_step_category_confirm', build_queue_data_with_xu($needSkipData));
    }

    /**
     * 处理下一批待确认的 维护节点状态
     * @param array $uuidList
     * @param $res
     * @return array
     * @throws Exception
     */
    private function handleNextStepCategoryConfirmList(array $uuidList, &$res)
    {
        $delayOrderCurrentStepCategoryIdUpdate = [];
        $delayOrderNextStepCategory = [];
        $nextConfirmStepCategoryList = model(DelayOrderTaskStepCategoryConfirmModel::class)->where(['parent_uuid' => ['IN', $uuidList]])->select();
        if (empty($nextConfirmStepCategoryList)) {
            // 没有下游节点，如果查到下游任务，追加该任务的下游任务确认【仅限 标准任务】
            $this->appendDelayOrderTaskStepCategoryConfirmByUuid($uuidList);
            $nextConfirmStepCategoryList = model(DelayOrderTaskStepCategoryConfirmModel::class)->where(['parent_uuid' => ['IN', $uuidList]])->select();
        }

        if (empty($nextConfirmStepCategoryList)) {
            return [$nextConfirmStepCategoryList, $delayOrderNextStepCategory];
        }
        $res['next_updated'] = model(DelayOrderTaskStepCategoryConfirmModel::class)->where(['id' => ['IN', array_column($nextConfirmStepCategoryList, 'id')]])->save(['is_active' => 'yes']);
        foreach (array_group_by($nextConfirmStepCategoryList, 'delay_order_id') as $delayOrderId => $tempNextConfirmStepCategoryList) {
            $tempNextConfirmStepCategoryList = array_sort_by($tempNextConfirmStepCategoryList, 'id', 'ASC', false);
            $delayOrderNextStepCategory[$delayOrderId] = $tempNextConfirmStepCategoryList[0]['step_category_id'];
            foreach ($tempNextConfirmStepCategoryList as $tempNextConfirmStepCategory) {
                $delayOrderCurrentStepCategoryIdUpdate[$tempNextConfirmStepCategory['step_category_id']][] = $tempNextConfirmStepCategory['delay_order_task_id'];
            }
        }
        foreach ($delayOrderCurrentStepCategoryIdUpdate as $stepCategoryId => $delayOrderTaskIdList) {
            model(DelayOrderTaskModel::class)->where(['id' => ['IN', $delayOrderTaskIdList]])->save(['confirming_step_category_id' => $stepCategoryId]);
        }
        return [$nextConfirmStepCategoryList, $delayOrderNextStepCategory];
    }

    /**
     * 延期单任务确认状态检查
     * @param array $delayOrderTaskIdList
     * @return array
     * @throws Exception
     */
    public function delayOrderTaskConfirmStatusCheck(array $delayOrderTaskIdList)
    {
        $delayOrderTaskList = model(DelayOrderTaskModel::class)
            ->where(['id' => ['IN', $delayOrderTaskIdList]])
            ->select();
        $delayOrderTaskStepCategoryConfirmList = model(DelayOrderTaskStepCategoryConfirmModel::class)
            ->where([
                'delay_order_task_id' => ['IN', $delayOrderTaskIdList],
            ])
            ->select();

        $delayOrderTaskStepCategoryConfirmListGroupByDelayOrderTaskId = array_group_by($delayOrderTaskStepCategoryConfirmList, 'delay_order_task_id');
        $delayOrderTaskUpdateList = [];
        foreach ($delayOrderTaskList as $delayOrderTask) {
            $delayOrderTaskConfirmStatus = '';
            if (!in_array($delayOrderTask['type'], [DelayOrderTaskModel::TYPE_REQUEST_DELAY, DelayOrderTaskModel::TYPE_WORK_ORDER])) {
                // 不是申请延期 都是直接通过
                $delayOrderTaskConfirmStatus = DelayOrderTaskModel::CONFIRM_STATUS_YES;
            } else {
                $delayOrderTaskStepCategoryConfirmList = $delayOrderTaskStepCategoryConfirmListGroupByDelayOrderTaskId[$delayOrderTask['id']] ?? [];
                $isActive = false;
                foreach ($delayOrderTaskStepCategoryConfirmList as $delayOrderTaskStepCategoryConfirm) {
                    if ($delayOrderTaskStepCategoryConfirm['is_active'] === 'yes') {
                        $isActive = true;
                    }
                }
                if ($delayOrderTask['manager_confirmed'] !== 'default') { // 制片已经确认过 直接填充确认的结果
                    $delayOrderTaskConfirmStatus = $delayOrderTask['manager_confirmed'];
                } elseif (empty($delayOrderTaskStepCategoryConfirmList)) { // 环节没有需要确认的 制片确认中
                    $delayOrderTaskConfirmStatus = DelayOrderTaskModel::CONFIRM_STATUS_PRODUCER_CONFIRMING;
                } elseif ($isActive) { // 环节还有正在确认的    环节确认中
                    $delayOrderTaskConfirmStatus = DelayOrderTaskModel::CONFIRM_STATUS_STEP_CATEGORY_CONFIRMING;
                } else { // 剩下的都是 制片确认中
                    $delayOrderTaskConfirmStatus = DelayOrderTaskModel::CONFIRM_STATUS_PRODUCER_CONFIRMING;
                }
            }
            if ($delayOrderTaskConfirmStatus != $delayOrderTask['confirm_status']) {
                $delayOrderTaskUpdateList[$delayOrderTaskConfirmStatus][] = $delayOrderTask['id'];
            }
        }

        foreach ($delayOrderTaskUpdateList as $confirmStatus => $delayOrderTaskIdList) {
            model(DelayOrderTaskModel::class)->where(['id' => ['IN', $delayOrderTaskIdList]])->save(['confirm_status' => $confirmStatus]);
        }
        return $delayOrderTaskUpdateList;
    }
}
